8 class WatchActionTest
extends MediaWikiTestCase
{
18 private $testWikiPage;
20 protected function setUp() {
23 $testTitle = Title
::newFromText( 'UTTest' );
24 $this->testWikiPage
= new WikiPage( $testTitle );
25 $testContext = new DerivativeContext( RequestContext
::getMain() );
26 $testContext->setTitle( $testTitle );
27 $this->watchAction
= new WatchAction( $this->testWikiPage
, $testContext );
33 protected function tearDown() {
36 Hooks
::clear( 'WatchArticle' );
37 Hooks
::clear( 'UnwatchArticle' );
41 * @covers WatchAction::getName()
43 public function testGetName() {
44 $this->assertEquals( 'watch', $this->watchAction
->getName() );
48 * @covers WatchAction::requiresUnblock()
50 public function testRequiresUnlock() {
51 $this->assertFalse( $this->watchAction
->requiresUnblock() );
55 * @covers WatchAction::doesWrites()
57 public function testDoesWrites() {
58 $this->assertTrue( $this->watchAction
->doesWrites() );
62 * @covers WatchAction::onSubmit()
63 * @covers WatchAction::doWatch()
65 public function testOnSubmit() {
66 /** @var Status $actual */
67 $actual = $this->watchAction
->onSubmit( [] );
69 $this->assertTrue( $actual->isGood() );
73 * @covers WatchAction::onSubmit()
74 * @covers WatchAction::doWatch()
76 public function testOnSubmitHookAborted() {
77 Hooks
::register( 'WatchArticle', function () {
81 /** @var Status $actual */
82 $actual = $this->watchAction
->onSubmit( [] );
84 $this->assertInstanceOf( Status
::class, $actual );
85 $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
89 * @covers WatchAction::checkCanExecute()
91 public function testShowUserNotLoggedIn() {
92 $notLoggedInUser = new User();
93 $testContext = new DerivativeContext( $this->watchAction
->getContext() );
94 $testContext->setUser( $notLoggedInUser );
95 $watchAction = new WatchAction( $this->testWikiPage
, $testContext );
96 $this->setExpectedException( UserNotLoggedIn
::class );
102 * @covers WatchAction::checkCanExecute()
104 public function testShowUserLoggedInNoException() {
105 $loggedInUser = $this->getMock( User
::class );
106 $loggedInUser->method( 'isLoggedIn' )->willReturn( true );
107 $testContext = new DerivativeContext( $this->watchAction
->getContext() );
108 $testContext->setUser( $loggedInUser );
109 $watchAction = new WatchAction( $this->testWikiPage
, $testContext );
113 $watchAction->show();
114 } catch ( UserNotLoggedIn
$e ) {
117 $this->assertNull( $exception,
118 'UserNotLoggedIn exception should not be thrown if user is logged in.' );
122 * @covers WatchAction::onSuccess()
124 public function testOnSuccessMainNamespaceTitle() {
125 $testContext = $this->getMock(
126 DerivativeContext
::class,
128 [ $this->watchAction
->getContext() ]
130 $testOutput = new OutputPage( $testContext );
131 $testContext->setOutput( $testOutput );
132 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
133 return new RawMessage( $msgKey );
135 $watchAction = new WatchAction( $this->testWikiPage
, $testContext );
137 $watchAction->onSuccess();
139 $this->assertEquals( '<p>addedwatchtext
140 </p>', $testOutput->getHTML() );
144 * @covers WatchAction::onSuccess()
146 public function testOnSuccessTalkPage() {
147 $testContext = $this->getMock(
148 DerivativeContext
::class,
150 [ $this->watchAction
->getContext() ]
152 $testOutput = new OutputPage( $testContext );
153 $testContext->method( 'getOutput' )->willReturn( $testOutput );
154 $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
155 return new RawMessage( $msgKey );
157 $talkPageTitle = Title
::newFromText( 'Talk:UTTest' );
158 $testContext->setTitle( $talkPageTitle );
159 $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
161 $watchAction->onSuccess();
163 $this->assertEquals( '<p>addedwatchtext-talk
164 </p>', $testOutput->getHTML() );
168 * @covers WatchAction::doWatch()
170 public function testDoWatchNoCheckRights() {
171 $notPermittedUser = $this->getMock( User
::class );
172 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
174 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $notPermittedUser, false );
176 $this->assertTrue( $actual->isGood() );
180 * @covers WatchAction::doWatch()
182 public function testDoWatchUserNotPermittedStatusNotGood() {
183 $notPermittedUser = $this->getMock( User
::class );
184 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
186 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $notPermittedUser, true );
188 $this->assertFalse( $actual->isGood() );
192 * @covers WatchAction::doWatch()
194 public function testDoWatchCallsUserAddWatch() {
195 $permittedUser = $this->getMock( User
::class );
196 $permittedUser->method( 'isAllowed' )->willReturn( true );
197 $permittedUser->expects( $this->once() )
198 ->method( 'addWatch' )
199 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ), $this->equalTo( true ) );
201 $actual = WatchAction
::doWatch( $this->testWikiPage
->getTitle(), $permittedUser );
203 $this->assertTrue( $actual->isGood() );
207 * @covers WatchAction::doUnWatch()
209 public function testDoUnWatchWithoutRights() {
210 $notPermittedUser = $this->getMock( User
::class );
211 $notPermittedUser->method( 'isAllowed' )->willReturn( false );
213 $actual = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $notPermittedUser );
215 $this->assertFalse( $actual->isGood() );
219 * @covers WatchAction::doUnWatch()
221 public function testDoUnWatchUserHookAborted() {
222 $permittedUser = $this->getMock( User
::class );
223 $permittedUser->method( 'isAllowed' )->willReturn( true );
224 Hooks
::register( 'UnwatchArticle', function () {
228 $status = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $permittedUser );
230 $this->assertFalse( $status->isGood() );
231 $errors = $status->getErrors();
232 $this->assertEquals( 1, count( $errors ) );
233 $this->assertEquals( 'hookaborted', $errors[0]['message'] );
237 * @covers WatchAction::doUnWatch()
239 public function testDoUnWatchCallsUserRemoveWatch() {
240 $permittedUser = $this->getMock( User
::class );
241 $permittedUser->method( 'isAllowed' )->willReturn( true );
242 $permittedUser->expects( $this->once() )
243 ->method( 'removeWatch' )
244 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ) );
246 $actual = WatchAction
::doUnWatch( $this->testWikiPage
->getTitle(), $permittedUser );
248 $this->assertTrue( $actual->isGood() );
252 * @covers WatchAction::getWatchToken()
254 public function testGetWatchTokenNormalizesToWatch() {
255 $user = $this->getMock( User
::class );
256 $user->expects( $this->once() )
257 ->method( 'getEditToken' )
258 ->with( $this->equalTo( 'watch' ) );
260 WatchAction
::getWatchToken( $this->watchAction
->getTitle(), $user, 'INVALID_ACTION' );
264 * @covers WatchAction::getWatchToken()
266 public function testGetWatchTokenProxiesUserGetEditToken() {
267 $user = $this->getMock( User
::class );
268 $user->expects( $this->once() )->method( 'getEditToken' );
270 WatchAction
::getWatchToken( $this->watchAction
->getTitle(), $user );
274 * @covers WatchAction::doWatchOrUnwatch()
276 public function testDoWatchOrUnwatchUserNotLoggedIn() {
277 $user = $this->getLoggedInIsWatchedUser( false );
278 $user->expects( $this->never() )->method( 'removeWatch' );
279 $user->expects( $this->never() )->method( 'addWatch' );
281 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
283 $this->assertTrue( $status->isGood() );
287 * @covers WatchAction::doWatchOrUnwatch()
289 public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
290 $user = $this->getLoggedInIsWatchedUser();
291 $user->expects( $this->never() )->method( 'removeWatch' );
292 $user->expects( $this->never() )->method( 'addWatch' );
294 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
296 $this->assertTrue( $status->isGood() );
300 * @covers WatchAction::doWatchOrUnwatch()
302 public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
303 $user = $this->getLoggedInIsWatchedUser( true, false );
304 $user->expects( $this->never() )->method( 'removeWatch' );
305 $user->expects( $this->never() )->method( 'addWatch' );
307 $status = WatchAction
::doWatchOrUnwatch( false, $this->watchAction
->getTitle(), $user );
309 $this->assertTrue( $status->isGood() );
313 * @covers WatchAction::doWatchOrUnwatch()
315 public function testDoWatchOrUnwatchWatchesIfWatch() {
316 $user = $this->getLoggedInIsWatchedUser( true, false );
317 $user->expects( $this->never() )->method( 'removeWatch' );
318 $user->expects( $this->once() )
319 ->method( 'addWatch' )
320 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ), $this->equalTo( false ) );
322 $status = WatchAction
::doWatchOrUnwatch( true, $this->watchAction
->getTitle(), $user );
324 $this->assertTrue( $status->isGood() );
328 * @covers WatchAction::doWatchOrUnwatch()
330 public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
331 $user = $this->getLoggedInIsWatchedUser();
332 $user->method( 'isAllowed' )->willReturn( true );
333 $user->expects( $this->never() )->method( 'addWatch' );
334 $user->expects( $this->once() )
335 ->method( 'removeWatch' )
336 ->with( $this->equalTo( $this->testWikiPage
->getTitle() ) );
338 $status = WatchAction
::doWatchOrUnwatch( false, $this->watchAction
->getTitle(), $user );
340 $this->assertTrue( $status->isGood() );
344 * @param bool $isLoggedIn Whether the user should be "marked" as logged in
345 * @param bool $isWatched The value any call to isWatched should return
346 * @return PHPUnit_Framework_MockObject_MockObject
348 private function getLoggedInIsWatchedUser( $isLoggedIn = true, $isWatched = true ) {
349 $user = $this->getMock( User
::class );
350 $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
351 $user->method( 'isWatched' )->willReturn( $isWatched );